#include "serial_helper.h"
#include <iostream>
#include "common.h"

// shared_ptr<serial_port> SerialHelper::serial_port_ = nullptr;
// char SerialHelper::receiveData[] = {0};
SerialHelper::SerialHelper()
     : config_(),
      status_timer_(io_),
      name_()
   {
    rec_flag=0;
    memset(receiveData, 0, sizeof(receiveData));
}

SerialHelper::~SerialHelper()
{
    if (serial_port_ == nullptr)
        serial_port_->close();
}

void SerialHelper::run()
{
    run_thread_ = std::thread(&SerialHelper::runThreadFunc, this);
    run_thread_.detach();
    read_thread_ = std::thread(&SerialHelper::read, this);
    read_thread_.detach();
}

void SerialHelper::open(const std::string name,SerialConfig config)
{
    try
    {
        name_=name;
        config_=config;
        if (serial_port_ == nullptr)
            serial_port_ = std::make_shared<serial_port>(io_);

        std::string port = "/dev/" + config_.port;
        std::cout << "connect port: " << port << ", baud: " << config_.baud << std::endl;
        boost::system::error_code ec = serial_port_->open(port, ec_);
        std::cout << "ec: " << ec.value() << std::endl;

        // 设置串口参数
        serial_port_->set_option(serial_port::baud_rate(config_.baud));
        serial_port_->set_option(serial_port::flow_control(serial_port::flow_control::none));
        serial_port_->set_option(serial_port::parity(serial_port::parity::none));
        serial_port_->set_option(serial_port::stop_bits(serial_port::stop_bits::one));
        serial_port_->set_option(serial_port::character_size(8));
        rec_flag=0;
        startTask();
    }
    catch (std::exception &err)
    {
        // std::cout << "Exception Error: " << err.what() << std::endl;
    }
}

void SerialHelper::read()
{
    while (1)
    {
        //rec_flag=0;
        if (serial_port_ != nullptr && serial_port_->is_open())
        {
            int size = serial_port_->read_some(boost::asio::buffer(receiveData));
            MsgBlock block;
            msg_buf_.clear();
            for (int i = 0; i < size; i++)
                 msg_buf_.push_back(receiveData[i]);
            block.vec = msg_buf_;
          //   recv_msg_callback_(block);
             rec_flag=1;
        //   std::cout << "recv size: " << size << ", msg: " << receiveData << std::endl;
           /* for (int i = 0; i < size; i++)
            {
                msg_buf_.push_back(receiveData[i]);
                 if (receiveData[i] == FRAME_TAIL)
                {
                    if (recv_msg_callback_ != nullptr)
                    {
                        MsgBlock block;
                        block.vec = msg_buf_;
                        if (block.isValid())
                        {
                            recv_msg_callback_(block);
                        }
                        msg_buf_.clear();
                    }
                }
            }
            */
        }
    }
}

void SerialHelper::runThreadFunc()
{
   //  startAsyncRead();
    io_.run();
}

// void SerialHelper::read(MsgBlock &msg_block)
// {
//     memset(receiveData, 0, sizeof(receiveData));
//     int size = serial_port_->read_some(boost::asio::buffer(receiveData));
//     msg_block.vec = std::vector<char>(receiveData, receiveData + sizeof(receiveData) / sizeof(char));
// }

void SerialHelper::handleStatusInfo(const boost::system::error_code &ec)
{
    // // std::cout << "check valid" << std::endl;
    if (!serial_port_->is_open())
    {
        // std::cout << name_ << " serial is invalid" << std::endl;
        serial_port_->close();
       // open();
    }

    status_timer_.expires_from_now(std::chrono::seconds(DATA_BEAT));
    status_timer_.async_wait(
        std::bind(&SerialHelper::handleStatusInfo, this, std::placeholders::_1));
}

void SerialHelper::startTask()
{
    // 开启定时器：
    status_timer_.expires_from_now(std::chrono::seconds(DATA_BEAT));
    status_timer_.async_wait(
        std::bind(&SerialHelper::handleStatusInfo, this, std::placeholders::_1));
}

void SerialHelper::close()
{
    serial_port_->close();
}

void SerialHelper::writeS(std::string &buf)
{
    boost::system::error_code ec;
    int size = serial_port_->write_some(boost::asio::buffer(buf), ec);
    if (size == 0)
    {
        serial_port_->close();
       // open();
    }
   // std::cout << name_ << " send ec: " << ec.message() << std::endl;
}

void SerialHelper::write(std::vector<u8> &buf)
{
    print(buf, "serial send:");
    boost::system::error_code ec;
    int size = serial_port_->write_some(boost::asio::buffer(buf), ec);
    if (size == 0)
    {
        serial_port_->close();
       // open();
    }
}
